package edu.towson.cosc490.incaseofemergency;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
import edu.towson.cosc490.incaseofemergency.objects.Constants;
import edu.towson.cosc490.incaseofemergency.objects.SupplyKitData;
import edu.towson.cosc490.incaseofemergency.objects.SupplyKitItem;


public class SupplyKit extends ListActivity {
	private SupplyKitData supplykitDB;
	private ListView itemListView;
	private Button allSupplyItemButton;
	private Button fireSupplyItemButton;
	private Button floodSupplyItemButton;
	private Button fluSupplyItemButton;
	private Button earthquakeSupplyItemButton;
	private Button hurricaneSupplyItemButton;
	private int selectedKitType;
	private TextView textKitType;
	private static final String errorTag = "catchError";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_supply_kit);
		supplykitDB = new SupplyKitData(this);
    	SharedPreferences settings = getPreferences(0);
    	boolean firstRun = settings.getBoolean("first_run", true);
    	if(firstRun){
    		initDatabase();
    	}
    	SharedPreferences.Editor editor = settings.edit();
    	editor.putBoolean("first_run", false);
    	editor.commit();
		initLayout();
		registerForContextMenu(getListView());		
		//Need to define if-else tree for type of kit being launched into, based on extras
		Intent intent = getIntent();
		int initialKitType = intent.getIntExtra("kitType", 0);
		
		selectedKitType = -1;
		updateList(initialKitType);
		Toast toast = Toast.makeText(getApplicationContext(), "Swipe top of screen to see all Kit Types.", Toast.LENGTH_LONG);
		toast.show();
	}
	
	public void onResume(){
		super.onResume();
		int temp = selectedKitType;
		selectedKitType = -1;
		updateList(temp);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.layout.supply_options_menu, menu);
		MenuItem addItem = (MenuItem) menu.findItem(R.id.supply_option_add);
		addItem.setIntent(new Intent(this, ItemDetailAdd.class));
		return true;
	}
	
	public boolean OnOptionsItemSelected(MenuItem item){
		return true;
	}
	
	public void OnStop(){
		supplykitDB.close();
		super.onStop();
	}
	
    private void initLayout(){
    	textKitType = (TextView) this.findViewById(R.id.textViewSupplyKitType);
    	allSupplyItemButton = (Button) this.findViewById(R.id.buttonFullSupplyKit);
    	allSupplyItemButton.setOnClickListener(new Button.OnClickListener(){
    		public void onClick(View v){
    			updateList(Constants.ALL_SUPPLY_ITEMS);
    		}
    	});
    	fireSupplyItemButton = (Button) this.findViewById(R.id.buttonFireSupplyKit);
    	fireSupplyItemButton.setOnClickListener(new Button.OnClickListener(){
    		public void onClick(View v){
    			updateList(Constants.FIRE_SUPPLY_ITEMS);
    		}
    	});
    	floodSupplyItemButton = (Button) this.findViewById(R.id.buttonFloodSupplyKit);
    	floodSupplyItemButton.setOnClickListener(new Button.OnClickListener(){
    		public void onClick(View v){
    			updateList(Constants.FLOOD_SUPPLY_ITEMS);
    		}
    	});
    	fluSupplyItemButton = (Button) this.findViewById(R.id.buttonFluSupplyKit);
    	fluSupplyItemButton.setOnClickListener(new Button.OnClickListener(){
    		public void onClick(View v){
    			updateList(Constants.FLU_SUPPLY_ITEMS);
    		}
    	});
    	earthquakeSupplyItemButton = (Button) this.findViewById(R.id.buttonEarthquakeSupplyKit);
    	earthquakeSupplyItemButton.setOnClickListener(new Button.OnClickListener(){
    		public void onClick(View v){
    			updateList(Constants.EARTHQUAKE_SUPPLY_ITEMS);
    		}
    	});
    	hurricaneSupplyItemButton = (Button) this.findViewById(R.id.buttonHurricaneSupplyKit);
    	hurricaneSupplyItemButton.setOnClickListener(new Button.OnClickListener(){
    		public void onClick(View v){
    			updateList(Constants.HURRICANE_SUPPLY_ITEMS);
    		}
    	});
    	itemListView = getListView();
    }
    
    private void updateList(int kitType){
    	boolean updatedCursor = false;
    	Cursor supplyListCursor = null;
    	switch(kitType){
    		case Constants.ALL_SUPPLY_ITEMS:
    			if( selectedKitType != Constants.ALL_SUPPLY_ITEMS){
    				supplyListCursor = getSupplyKitItems();
    		    	selectedKitType = Constants.ALL_SUPPLY_ITEMS;
    		    	textKitType.setText("All Supply Kit Items:");
    		    	updatedCursor = true;
    			}
    			break;
    		case Constants.FIRE_SUPPLY_ITEMS:
    			if( selectedKitType != Constants.FIRE_SUPPLY_ITEMS){
    				supplyListCursor = getFireKitItems();
    		    	selectedKitType = Constants.FIRE_SUPPLY_ITEMS;
    		    	textKitType.setText("Fire Kit Items:"); 
    		    	updatedCursor = true;
    			}
    			break;
    		case Constants.FLOOD_SUPPLY_ITEMS:
    			if( selectedKitType != Constants.FLOOD_SUPPLY_ITEMS){
    				supplyListCursor = getFloodKitItems();
    		    	selectedKitType = Constants.FLOOD_SUPPLY_ITEMS;
    		    	textKitType.setText("Flood Kit Items:"); 
    		    	updatedCursor = true;
    			}
    			break;
    		case Constants.FLU_SUPPLY_ITEMS:
    			if( selectedKitType != Constants.FLU_SUPPLY_ITEMS){
    				supplyListCursor = getFluKitItems();
    		    	selectedKitType = Constants.FLU_SUPPLY_ITEMS;
    		    	textKitType.setText("Flu Kit Items:"); 
    		    	updatedCursor = true;
    			}
    			break;
    		case Constants.EARTHQUAKE_SUPPLY_ITEMS:
    			if( selectedKitType != Constants.EARTHQUAKE_SUPPLY_ITEMS){
    				supplyListCursor = getEarthquakeKitItems();
    		    	selectedKitType = Constants.EARTHQUAKE_SUPPLY_ITEMS;
    		    	textKitType.setText("Earthquake Kit Items:"); 
    		    	updatedCursor = true;
    			}
    			break;
    		case Constants.HURRICANE_SUPPLY_ITEMS:
    			if( selectedKitType != Constants.HURRICANE_SUPPLY_ITEMS){
    				supplyListCursor = getHurricaneKitItems();
    		    	selectedKitType = Constants.HURRICANE_SUPPLY_ITEMS;
    		    	textKitType.setText("Hurricane Kit Items:"); 
    		    	updatedCursor = true;
    			}
    			break;
    		default:
    			supplyListCursor = getSupplyKitItems();
		    	selectedKitType = Constants.ALL_SUPPLY_ITEMS;
		    	updatedCursor = true;
    			break;
    	}
    		if(updatedCursor){
    			String[] FROM = {Constants._ID, Constants.PERISHABLE, Constants.AMOUNT_OWNED, Constants.AMOUNT_REQUIRED, Constants.ITEM_NAME, Constants.EXPIRATON_DATE};
    	    	int[] TO = {R.id.itemId, R.id.itemPerishable, R.id.itemAmountOwned, R.id.itemAmountRequired, R.id.itemName, R.id.itemExpirationDate};
    	    	SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.supply_list_item, supplyListCursor, FROM, TO);
    			setListAdapter(sca);
    			stopManagingCursor(supplyListCursor);
    		}
    }

	 // Query the database and return a Cursor of to-do items.
    @SuppressWarnings("deprecation")
	private Cursor getSupplyKitItems(){
    	SQLiteDatabase db = supplykitDB.getReadableDatabase();
		Cursor cursor = db.query(Constants.KIT_TABLE_NAME, null, null, null, null, null, Constants.ITEM_NAME +" ASC");

		startManagingCursor(cursor);
		return cursor;
    }
    
	private Cursor getFireKitItems(){
    	SQLiteDatabase db = supplykitDB.getReadableDatabase();
		Cursor cursor = db.query(Constants.KIT_TABLE_NAME, null, Constants.KIT_TYPE_FILTER +"=?", new String[]{"1"}, null, null, Constants.ITEM_NAME+" ASC");
		startManagingCursor(cursor);
		return cursor;
    }
	
	private Cursor getFloodKitItems(){
    	SQLiteDatabase db = supplykitDB.getReadableDatabase();
		Cursor cursor = db.query(Constants.KIT_TABLE_NAME, null, Constants.KIT_TYPE_FILTER+"=?", new String[]{"2"}, null, null, Constants.ITEM_NAME+" ASC");
		startManagingCursor(cursor);
		return cursor;
    }
	
	private Cursor getFluKitItems(){
    	SQLiteDatabase db = supplykitDB.getReadableDatabase();
		Cursor cursor = db.query(Constants.KIT_TABLE_NAME, null, Constants.KIT_TYPE_FILTER+"=?", new String[]{"3"}, null, null, Constants.ITEM_NAME+" ASC");
		startManagingCursor(cursor);
		return cursor;
    }
	
	private Cursor getEarthquakeKitItems(){
    	SQLiteDatabase db = supplykitDB.getReadableDatabase();
		Cursor cursor = db.query(Constants.KIT_TABLE_NAME, null, Constants.KIT_TYPE_FILTER+"=?", new String[]{"4"}, null, null, Constants.ITEM_NAME+" ASC");
		startManagingCursor(cursor);
		return cursor;
    }
	
	private Cursor getHurricaneKitItems(){
    	SQLiteDatabase db = supplykitDB.getReadableDatabase();
		Cursor cursor = db.query(Constants.KIT_TABLE_NAME, null, Constants.KIT_TYPE_FILTER+"=?", new String[]{"5"}, null, null, Constants.ITEM_NAME+" ASC");
		startManagingCursor(cursor);
		return cursor;
    }
    
    private void addSupplyKitItem(SupplyKitItem item){
    	SQLiteDatabase database = supplykitDB.getWritableDatabase();
    	ContentValues values = new ContentValues();
    	values.put(Constants.ITEM_NAME, item.getItemName());
    	values.put(Constants.AMOUNT_REQUIRED, item.getSuggestedQuantity());
    	values.put(Constants.AMOUNT_OWNED, item.getOwnedQuantity());
    	values.put(Constants.PERISHABLE, item.perishableString());
    	values.put(Constants.EXPIRATON_DATE, item.getExpirationDate());
    	values.put(Constants.KIT_TYPE_FILTER, item.getKitType());
    	database.insertOrThrow(Constants.KIT_TABLE_NAME, null, values);
    	database.close();
    	//Update view
    }
    
    private void deleteSupplyKitItem(String itemID){
    	SQLiteDatabase database = supplykitDB.getWritableDatabase();
    	database.delete(Constants.KIT_TABLE_NAME, "_ID = " + itemID, null);
    	database.close();
    	int refreshType = selectedKitType;
    	selectedKitType = -1;
    	updateList(refreshType);
    }
    
    private void initDatabase(){
    	InputStream databaseXMLFile = (InputStream)getResources().openRawResource(R.raw.initial_database_values);
    	DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    	DocumentBuilder docBuilder = null;
    	try{
    		docBuilder = docFactory.newDocumentBuilder();
    	} catch(ParserConfigurationException e){
    		Log.w(errorTag, "Parser Config exception: "+ e);
    	}
    	try{
    		Document docData = docBuilder.parse(databaseXMLFile);
    		docData.getDocumentElement().normalize();
    		NodeList nodeList = docData.getElementsByTagName("item");
    		for (int index = 0; index < nodeList.getLength(); index++){
    			Node itemNode = nodeList.item(index);
    			if(itemNode.getNodeType() == Node.ELEMENT_NODE){
    				Element elementItem = (Element) itemNode;
    				SupplyKitItem itemObject = new SupplyKitItem(
    						elementItem.getAttribute("name"),
    						Integer.parseInt(elementItem.getElementsByTagName("suggested_quantity").item(0).getTextContent()),
    						Boolean.parseBoolean(elementItem.getElementsByTagName("perishable").item(0).getTextContent()),
    						elementItem.getElementsByTagName("expiration_date").item(0).getTextContent(),
    						Integer.parseInt(elementItem.getElementsByTagName("kit_type").item(0).getTextContent())
    						);
    				addSupplyKitItem(itemObject);
    			}
    		}
    	} catch(IOException e){
    		Log.w(errorTag, "IO exception on xml Document: " + e);
    	} catch(SAXException e){
    		Log.w(errorTag, e.getMessage());
    	}
    }
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    	super.onCreateContextMenu(menu, v, menuInfo);
    	menu.setHeaderTitle("Select an action");
    	menu.add(1, v.getId(), 0, "Edit Item");
    	menu.add(2, v.getId(), 1, "Delete Item");
    	menu.add(3, v.getId(), 2, "Search for Item");
    }
    
    @Override
    public boolean onContextItemSelected(MenuItem item) {
    	AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    	View listItemView = info.targetView;
    	TextView itemId = (TextView)listItemView.findViewById(R.id.itemId);
    	TextView itemName = (TextView)listItemView.findViewById(R.id.itemName);
    	TextView itemAmountOwned = (TextView)listItemView.findViewById(R.id.itemAmountOwned);
    	TextView itemAmountRequired = (TextView)listItemView.findViewById(R.id.itemAmountRequired);
    	TextView itemPerishable = (TextView)listItemView.findViewById(R.id.itemPerishable);
    	TextView itemExpiration = (TextView)listItemView.findViewById(R.id.itemExpirationDate);
    	final LocationManager locationManager =
    	        (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    	
    	if(item.getTitle() == "Edit Item"){
    		Intent editItemIntent = new Intent(this, ItemDetailEdit.class);
    		editItemIntent.putExtra("itemId", itemId.getText().toString());
    		editItemIntent.putExtra("itemName" , itemName.getText().toString());
    		editItemIntent.putExtra("itemAmountOwned" , itemAmountOwned.getText().toString());
    		editItemIntent.putExtra("itemAmountRequired" , itemAmountRequired.getText().toString());
    		editItemIntent.putExtra("itemPerishable" , itemPerishable.getText().toString());
    		editItemIntent.putExtra("itemExpiration" , itemExpiration.getText().toString());
    		startActivity(editItemIntent);
    	}
        else if(item.getTitle() == "Delete Item")
        	deleteSupplyKitItem(itemId.getText().toString());
        else if(item.getTitle() == "Search for Item") {
        	try {
				String itemSearch = itemName.getText().toString();
				itemSearch = itemSearch.replace(" ", "+");
				itemSearch = itemSearch + "+store";
				Location myLoc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
				if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
					Log.i("debug", "gps disabled");
					AlertDialog.Builder alert = new AlertDialog.Builder(this);

					alert.setMessage("GPS is disabled.  Please go to phone settings and enable Location Services to use this feature.");

					alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int whichButton) {
						}
					});
					
					alert.show();
				}
				Intent mapIntent = new Intent(
						android.content.Intent.ACTION_VIEW, Uri
						.parse("geo:" + myLoc.getLatitude() + "," + myLoc.getLongitude() + "?q=" + itemSearch));
				startActivity(mapIntent);
				} catch (Exception e) {
				}
			}
        else
        	return false;
    	return true;
    }
}
